package com.tegistuff.webos.run.debugger.commands;

import com.palm.webos.tools.internal.debugger.Dispatcher;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

/**
 * WebOSDebuggerCommand.java
 *
 * This is the base class for all commands directly interacting with the V8 debugger.
 *
 * Copyright (C) 2011-2012 Timo Tegtmeier.
 * All rights reserved.
 */
public abstract class WebOSDebuggerCommand extends BaseWebOSCommand implements Dispatcher.ResponseListener {

    protected JSONObject ourResponse;

    protected int retries = 3;

    protected WebOSDebuggerCommand() {
    }

    protected final void runRequest(JSONObject request) {
        try {
            ourAppDebugSession.sendRequest(request, this);
        } catch (IOException e) {
            ourDebugSession.reportError("Unable to communicate with debugger.");
        }
    }

    @Override
    public final void requestFailed(JSONObject jsonObject) {
        if(!retry()) {
            ourDebugSession.reportError("Debugger command failed.");
            done();
        }
    }

    @Override
    public final void responseReceived(JSONObject request, JSONObject response) {
        ourResponse = response;
        try {
            if(response.has("running")) {
                if(response.getBoolean("running")) {
                    ourDebugProcess.getDebuggerProxy().setRunning();
                } else {
                    ourDebugProcess.getDebuggerProxy().setSuspended();
                }
            }

            if(response.optBoolean("success", true) || ignoreSuccessState()) {
                onSuccess();
            } else {
                if(!retry()) {
                    ourDebugSession.reportError("Command could not be executed successfully.");
                } else {
                    return; // do not proceed to next command
                }
            }
        } catch (JSONException e) {
            ourDebugProcess.reportInternalError(e);
        }
        done();
    }

    private boolean retry() {
        retries--;
        if(retries > 0) {
            try {
                execute();
                return true;
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }

    protected boolean ignoreSuccessState() {
        return false;
    }

    protected abstract void onSuccess() throws JSONException;
}
